package Ms

import (
	"fmt"
	"db2s/ETL"
	"db2s/global"
	"db2s/parDef"
	"db2s/ref"
	"math"
)

func (sum SumF) Set(parameter string, value any) (err error) {
	return ref.UpdateStructJsonValue(sum, parameter, value)
}
func (sum SumF) Result(object string) global.Return {
	switch object {
	default:
		return global.Return{}
	}
}

func (sum SumF) Rows(parameter parDef.Parameter) (result global.Return, err error) {
	var execSql []string
	var event = "[MsRows]"
	execSql = append(execSql, fmt.Sprintf("SELECT "+
		"SUM(p.rows) AS [tableRows] "+
		"FROM "+
		"sys.objects AS o "+
		"JOIN "+
		"sys.tables AS t ON o.object_id = t.object_id "+
		"JOIN "+
		"sys.partitions AS p ON t.object_id = p.object_id "+
		"JOIN "+
		"sys.schemas AS s ON o.schema_id = s.schema_id "+
		"WHERE "+
		"o.type = 'U' "+
		"AND s.name = '%v' "+
		"AND o.name = '%v' "+
		"AND p.index_id IN (0, 1) "+
		"GROUP BY o.name ", parameter.Object.Schema, parameter.Object.Table))
	if result, err = forExecQuerySql(event, parameter, ETL.String, execSql); err != nil {
		err = ref.ErrAddPrintf("Rows", err)
		return
	}
	if result.Result == nil {
		return
	}
	if result.Result, err = stringAnyToInt64(result.Result); err != nil {
		err = ref.ErrAddPrintf("Rows", err)
		return
	}
	return
}
func (sum SumF) Count(parameter parDef.Parameter) (result global.Return, err error) {
	//var execSql []string
	//var event = "[MyRows]"
	//execSql = append(execSql, fmt.Sprintf(
	//	"SELECT %v "+
	//		"count(1) as [tableRows] "+
	//		"from %v where 1=1 "+
	//		"%v %v ",
	//	rowsLimitC(parameter.Options.RowsLimit),
	//	tableObject(parameter.Object.Schema, parameter.Object.Table, parameter.Object.Partition),
	//	whereFilter(parameter.Options.WhereSql),
	//	whereFilter(parameter.Options.WhereAdd),
	//))
	//if parameter.ExecSqlFunc != nil {
	//	//if result, err = parameter.ExecSqlFunc(modifyGetDbQueryOptions(parameter.GetDbQueryOptions(parameter), dataDispos.String), execSql); err != nil {
	//	//	err = ref.ErrAddPrintf(event, err)
	//	//	return
	//	//}
	//}
	//if parameter.ExecFunc != nil {
	//	result.Result,err = parameter.ExecFunc(result.Result,nil)
	//}
	return
}
func (sum SumF) Sum(parameter parDef.Parameter) (result global.Return, err error) {
	var sumValue int64
	if result, err = sum.Rows(parameter); err != nil || result.Result == nil {
		err = ref.ErrAddPrintf("Sum", err)
		return
	}
	sumValue = result.Result.(int64)
	if sumValue > 1000000 {
		return
	}
	if result, err = sum.Count(parameter); err != nil {
		err = ref.ErrAddPrintf("Sum", err)
		return
	}
	if result.Result == nil {
		return
	}
	return
}
func (sum SumF) DataSizeMB(parameter parDef.Parameter) (result global.Return, err error) {
	var execSql []string
	var event = "[DataSizeMB]"
	execSql = append(execSql, fmt.Sprintf("SELECT \n "+
		"CAST(ROUND(SUM(a.total_pages) * 8 / 1024.0, 2) AS DECIMAL(10, 2)) AS dataSizeMB\n "+
		"FROM \n "+
		"sys.tables AS t\n "+
		"JOIN \n"+
		"sys.indexes AS i ON t.object_id = i.object_id\n "+
		"JOIN \n"+
		"sys.partitions AS p ON i.object_id = p.object_id AND i.index_id = p.index_id\n "+
		"JOIN \n "+
		"sys.allocation_units AS a ON p.partition_id = a.container_id\n "+
		"WHERE \n"+
		"SCHEMA_NAME(t.schema_id) = '%v' \n"+
		"AND t.name = '%v' \n"+
		"GROUP BY \n t.name", parameter.Object.Schema, parameter.Object.Table))
	if result, err = forExecQuerySql(event, parameter, ETL.String, execSql); err != nil {
		err = ref.ErrAddPrintf("DataSizeMB", err)
		return
	}
	if result.Result == nil {
		return
	}
	if result.Result, err = stringAnyToFloat64(result.Result); err != nil {
		err = ref.ErrAddPrintf("DataSizeMB", err)
		return
	}
	return
}
func (sum SumF) IndexSizeMB(parameter parDef.Parameter) (result global.Return, err error) {
	var execSql []string
	var event = "[IndexSizeMB]"
	execSql = append(execSql, fmt.Sprintf("SELECT\n    "+
		"CAST(ROUND(SUM(s.used_page_count) * 8 / 1024.0, 2) AS DECIMAL(10, 2))  AS IndexSizeMB\n "+
		"FROM sys.dm_db_partition_stats  AS s \n "+
		"JOIN sys.indexes                AS i\n "+
		"ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id\n "+
		"WHERE s.[object_id] = object_id('%v.%v')", parameter.Object.Schema, parameter.Object.Table))
	if result, err = forExecQuerySql(event, parameter, ETL.String, execSql); err != nil {
		err = ref.ErrAddPrintf("IndexSizeMB",err)
		return
	}
	if result.Result == nil{return}
	if result.Result, err = stringAnyToFloat64(result.Result); err != nil {
		err = ref.ErrAddPrintf("IndexSizeMB",err)
		return
	}
	return
}
func (sum SumF) DataLength(parameter parDef.Parameter) (result global.Return, err error) {
	var dataSize, indexSize float64
	if result, err = sum.DataSizeMB(parameter); err != nil  {
		err = ref.ErrAddPrintf("DataLength",err)
		return
	}
	if result.Result == nil{return}
	dataSize = result.Result.(float64)
	if result, err = sum.IndexSizeMB(parameter); err != nil{
		err = ref.ErrAddPrintf("DataLength",err)
		return
	}
	if result.Result == nil{return}
	indexSize = result.Result.(float64)
	result.Result = math.Round((dataSize+indexSize)*100) / 100
	return
}

func (sum SumF) AvgRowsSize(parameter parDef.Parameter) (result global.Return, err error) {
	var execSql []string
	var event = "[AvgRowsSize]"
	execSql = append(execSql, fmt.Sprintf("SELECT \n    "+
		"CAST(ROUND(SUM(ps.row_count) / (SUM(ps.used_page_count) * 8.0), 2) AS DECIMAL(10, 2))  AS [AvgRowLength]\n "+
		"FROM \n    "+
		"sys.dm_db_partition_stats AS ps\n "+
		"JOIN \n    "+
		"sys.tables AS t ON ps.object_id = t.object_id\n "+
		"WHERE \n    "+
		"SCHEMA_NAME(t.schema_id) = '%v' \n"+
		"AND t.name = '%v'", parameter.Object.Schema, parameter.Object.Table))
	if result, err = forExecQuerySql(event, parameter, ETL.String, execSql); err != nil {
		err = ref.ErrAddPrintf("AvgRowsSize",err)
		return
	}
	if result.Result == nil{return}
	if result.Result, err = stringAnyToInt64(result.Result); err != nil {
		err = ref.ErrAddPrintf("AvgRowsSize",err)
		return
	}
	return
}
